<?php
namespace App\Models;

use App\Models\ComModel;

class SystemModel extends ComModel
{
    public $config;

    public function __construct(...$param)
    {
        parent::__construct();
    }

    public function save_config($param, $data)
    {
        if (!$param) {
            return ams_rt(1, '类型错误');
        } elseif (!$data) {
            return ams_rt(1, '数据为空');
        }
        $configLib = new ('App\Libraries\Config');
        $data = esc($data);
        $rs = $configLib->file($param, '配置文件', 32)->to_require($data);
        if (!$rs) {
            return ams_rt(1, '操作失败');
        }
        return ams_rt(0, '操作成功');
    }

    //安装系统
    public function install($data)
    {

        $data = esc($data);

        if (!preg_match('/^[\x7f-\xff\dA-Za-z\.\_]+$/', $data['admin']) || strlen($data['admin']) < 5) {
            return ams_rt(1, '管理员账号格式不正确');
        }

        if (!$data['email'] || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
            return ams_rt(1, 'Email格式不正确');
        }

        if (!is_file(WRITEPATH . 'install/menu.php')) {
            return ams_rt(1, '系统菜单不存在');
        }

        if (!is_file(WRITEPATH . 'install/rules.php')) {
            return ams_rt(1, '系统权限规则不存在');
        }

        if (!is_file(WRITEPATH . 'install/install.sql')) {
            return ams_rt(1, '系统表结构不存在');
        }

        // 导入表结构
        $dbprefix = $this->db->getPrefix();
        $this->_installQuery(str_replace('{dbprefix}', $dbprefix, file_get_contents(WRITEPATH . 'install/install.sql')));

        //初始化后台菜单
        $menuModel = model('App\Models\MenuModel');
        $menuModel->init();

        //权限规则
        $rbacModel = model('App\Models\RbacModel');
        $rbacModel->iniRule();
        $rbacModel->addRole(['name' => '创始人', 'status' => 1]);

        //站点设置
        $this->initSite($data);

        //初始化用户
        $userModel = model('App\Models\UserModel');
        $userModel->addGroup(['name' => '默认']);

        //创建创始人
        $adminModel = model('App\Models\AdminModel');
        $adminModel->addRoot($data['admin'], $data['password'], $data['email']);

        cache()->save('login_success', [
            '后台地址:' => '<a href="' . url('/admin', ['hashcode' => $data['hash']]) . '" target="_blank">后台登录</a>',
            '账号:' => $data['admin'],
            '密码:' => $data['password'],
        ], 3 * MINUTE);

        return ams_rt(0, 'ok');

    }

    //安装sql
    private function _installQuery($sql)
    {
        if (!$sql) {
            return null;
        }
        $sql_data = explode(';SQL_MOK_EOL', trim(str_replace([PHP_EOL, chr(13), chr(10)], 'SQL_MOK_EOL', $sql)));
        foreach ($sql_data as $query) {
            if (!$query) {
                continue;
            }
            $ret = '';
            $queries = explode('SQL_MOK_EOL', trim($query));
            foreach ($queries as $query) {
                if ((isset($query[0]) && isset($query[1]) && $query[0] . $query[1] == '--') || (isset($query[0]) && $query[0] == '#')) {
                    continue;
                }
                $ret .= $query;
            }
            if (!$ret) {
                continue;
            }
            $this->db->query($ret);
        }
    }

    // 数据执行
    private function query($sql)
    {
        if (!$sql) {
            return '';
        }
        $sql_data = explode(';SQL_MOK_EOL', trim(str_replace([PHP_EOL, chr(13), chr(10)], 'SQL_MOK_EOL', $sql)));
        foreach ($sql_data as $query) {
            if (!isset($query) || !$query) {
                continue;
            }
            $ret = '';
            $queries = explode('SQL_MOK_EOL', trim($query));
            foreach ($queries as $query) {
                $query[0] = isset($query[0]) && $query[0] == '#' ? $query[0] : '';
                $query[1] = isset($query[1]) && $query[0] == '--' ? $query[1] : '';
                $ret .= ($query[0] || $query[1]) ? $query : '';
            }
            if (!$ret) {
                continue;
            }
            if (!$this->db->simpleQuery(trim($ret))) {
                $rt = $this->db->error();
                $error = '**************************************************************************'
                    . PHP_EOL . $ret . PHP_EOL . $rt['message'] . PHP_EOL;
                $error .= '**************************************************************************' . PHP_EOL;
                file_put_contents(WRITEPATH . 'install.error', $error . PHP_EOL, FILE_APPEND);
            }
        }
    }

    //初始化站点设置
    public function initSite($data = [])
    {
        $site = [
            'SITE_ADMIN_LOG' => '1',
            'SITE_ADMIN_PAGESIZE' => '10',
            'SITE_KEY' => ams_syskey(),
            'SITE_HTTPS' => '0',
            'SITE_EMAIL' => '',
            'SITE_NAME' => 'CIAMS',
            'SITE_DOMAIN' => DOMAIN_NAME,
            'SITE_DOMAINS' => '',
            'SITE_ADMIN_HASHCODE' => $data['hash'],
            'SITE_HTML_DIR' => '',
            'SITE_THEME' => 'theme',
            'SITE_TEMPLATE' => 'default',
            'SITE_CLOSE' => '0',
            'SITE_CLOSE_MSG' => '网站关闭时的显示信息',
            'SITE_LANGUAGE' => 'zh-CN',
            'SITE_TITLE' => 'CIAMS',
            'SITE_SEOJOIN' => '_',
            'SITE_KEYWORDS' => 'CIAMS',
            'SITE_DESCRIPTION' => 'CIAMS',
            'SITE_MOBILE' => '',
            'SITE_MOBILE_OPEN' => '0',
            'SITE_LOGIN_LOCK' => '3',
            'SITE_LOGIN_LOCK_HOUR' => '10',
            'SITE_BLACKIP' => '0',
            'SITE_ATTACHMENT_PATH' => '', //附件上传路径
            'SITE_ATTACHMENT_URL' => '', //附件访问地址
            'SITE_IMAGE_CONTENT' => '1',
            'SITE_IMAGE_OVERLAY' => 'default.png',
            'SITE_IMAGE_FONT' => 'default.ttf',
            'SITE_IMAGE_RATIO' => '1',
            'SITE_IMAGE_WATERMARK' => '0',
            'SITE_IMAGE_VRTOFFSET' => '',
            'SITE_IMAGE_HOROFFSET' => '',
            'SITE_IMAGE_TYPE' => '0',
            'SITE_IMAGE_OPACITY' => '',
            'SITE_IMAGE_SIZE' => '16',
            'SITE_IMAGE_TEXT' => 'CIAMS',
            'SITE_IMAGE_VRTALIGN' => 'top',
            'SITE_IMAGE_HORALIGN' => 'left',
        ];
        $configLib = new ('App\Libraries\Config');
        $rs = $configLib->file('site', '站点配置文件', 32)->to_require_one($site);
        if (!$rs) {
            return ams_rt(1, '配置文件写入失败');
        }
        return ams_rt(0, 'ok');
    }

    public function insterLog($data)
    {
        $request = \Config\Services::request();
        $session = \Config\Services::session();
        $ip = $request->getIPAddress();
        if (!isset($data['userid']) || !$data['userid']) {
            $admin = $session->get('admin');
            $data['userid'] = $admin['userid'] ?? 0;
            $data['username'] = $admin['username'] ?? '';
        }

        $data = [
            'userid' => $data['userid'],
            'ip' => $ip,
            'inputtime' => time(),
            'year' => date('Y'),
            'month' => date('Y-m'),
            'day' => date('Y-m-d'),
            'url' => MOK_NOW_URL,
            'action' => $data['action'] ? $data['action'] : '',
        ];
        $data = esc($data);
        $this->db->table('admin_oplog')->insert($data);
        $id = $this->db->insertID();
        return $id;
    }

    public function get_attachment($id = 0)
    {
        if (!$id) {
            return false;
        }
        $data = $this->db->table('attachment')->where('id', $id)->get()->getRowArray();
        if (!$data) {
            return false;
        } elseif ($data['related']) {
            $info = $this->db->table('attachment_data')->where('id', $id)->get()->getRowArray();
        } else {
            $info = $this->db->table('attachment_unused')->where('id', $id)->get()->getRowArray();
        }
        if (!$info) {
            return false;
        }
        // 合并变量
        $info = $data + $info;
        return $info;

    }

    //获取mysql版本
    public function get_mysql_version()
    {
        $version = $this->db->getVersion();
        return $version;
    }

    //初始化设置
    public function init_setting()
    {
        // 写配置文件
        $sys = [
            'SITE_ADMIN_CODE' => '0', //后台登录验证码开关
            'SITE_ADMIN_LOG' => '0', //后台操作日志开关
            'SITE_ADMIN_PAGESIZE' => '10', //后台数据分页显示数量
            'SITE_PAGE_RNAME' => '0', //单页目录允许重复
            'SITE_CSRF' => '1', //跨站验证提交
            'SITE_KEY' => 'CIAMS' . md5(ams_randstr(16)), //安全密匙
            'SITE_HTTPS' => '0', //https模式
            'SITE_ATTACHMENT_DB' => '', //附件归属开启模式
            'SITE_ATTACHMENT_PATH' => '', //附件上传路径
            'SITE_ATTACHMENT_URL' => '', //附件访问地址
            'SITE_EMAIL' => '',
            'SITE_NAME' => '网站的名称',
            'SITE_DOMAIN' => '',
            'SITE_DOMAINS' => '',
            'SITE_HTML_DIR' => '',
            'SITE_MOBILE' => '',
            'SITE_CLOSE' => '0',
            'SITE_CLOSE_MSG' => '网站关闭时的显示信息',
            'SITE_LANGUAGE' => 'zh',
            'SITE_TITLE' => '网站首页SEO标题',
            'SITE_SEOJOIN' => '_',
            'SITE_KEYWORDS' => '网站SEO关键字',
            'SITE_DESCRIPTION' => '网站SEO描述信息',
            'SITE_MOBILE_OPEN' => '0',
            'SITE_IMAGE_CONTENT' => '1',
            'SITE_IMAGE_RATIO' => '1',
            'SITE_ADMIN_LOCK' => 0,
            'SITE_ADMIN_LOCK_HOUR' => 5,
        ];
        $this->db->table('setting')->where('param', 'site')->replace(['param' => 'site', 'value' => json_encode($site), 'updatetime' => time()]);
    }

    /**
     * 条件查询
     */
    private function _oplog_where(&$select, $param)
    {
        // 条件搜索
        if ($param) {

            if (isset($param['username'])) {
                $select->like('username', urldecode($param['username']));
            }

            if (isset($param['day'])) {
                $select->like('day', urldecode($param['day']));
            }

            // 时间搜索
            if (isset($param['sdate']) && $param['sdate']) {
                $select->where('addtime BETWEEN ' . max((int) strtotime($param['sdate'] . ' 00:00:00'), 1) . ' AND ' . ($param['edate'] ? (int) strtotime($param['edate'] . ' 23:59:59') : SITE_TIME));
            } elseif (isset($param['edate']) && $param['edate']) {
                $select->where('addtime BETWEEN 1 AND ' . (int) strtotime($param['edate'] . ' 23:59:59'));
            }
        }
        return $param;
    }

    /**
     * 数据分页显示
     */
    public function oplog_limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {

        $page = max(1, (int) $page);
        $total = (int) $total;

        unset($param['page']);
        if ($param) {
            $param = esc($param);
        }

        if ($size > 0 && !$total) {
            $select = $this->db->table('admin_oplog')->select('count(*) as total');
            $param = $this->_oplog_where($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：' . 'admin_oplog');
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table('admin_oplog');
        $order = isset($param['order']) ? esc($param['order']) : '';
        $param = $this->_oplog_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy('id', 'desc')->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . 'admin_oplog');
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        if ($data) {
            $userModel = model('App\Models\UserModel');
            foreach ($data as $k => $v) {
                $user = $userModel->getUserField($v['userid'], 'username,phone');
                $data[$k]['username'] = $user['username'] ?? 'USERID:' . $v['userid'];
            }
        }
        $param['order'] = $order;
        $param['total'] = $total;

        return [$data, $total, $param];
    }

    /**
     * 条件查询
     */
    private function _where_proset(&$select, $data)
    {
        if ($data) {

            if (isset($data['type']) && $data['type']) {
                $select->where('type', $data['type']);
            }

            if (isset($data['code']) && $data['code']) {
                $select->where('code', $data['code']);
            }

            if (isset($data['name']) && $data['name']) {
                $select->like('name', $data['name'], 'both');
            }

            if (isset($data['status']) && ($data['status'] == 1 || $data['status'] == '0')) {
                $select->where('status', $data['status']);
            }

            // 时间搜索
            if (isset($data['start']) && $data['start']) {
                $data['end'] = strtotime(date('Y-m-d 23:59:59', $data['end'] ? $data['end'] : time()));
                $data['start'] = strtotime(date('Y-m-d 00:00:00', $data['start']));
                $select->where('addtime BETWEEN ' . $data['start'] . ' AND ' . $data['end']);
            } elseif (isset($data['end']) && $data['end']) {
                $data['end'] = strtotime(date('Y-m-d 23:59:59', $data['end']));
                $data['start'] = 1;
                $select->where('addtime BETWEEN ' . $data['start'] . ' AND ' . $data['end']);
            }
        }
        return $data;
    }

    /**
     * 数据分页显示
     */
    public function limit_page_proset($page = 0, $size = 10, $total = 0, $param = [])
    {
        $page = max(1, (int) $page);
        $total = (int) $total;
        unset($param['page']);
        if ($param) {
            $param = esc($param);
        }
        if ($size > 0 && !$total) {
            $select = $this->db->table('proset')->select('count(*) as total');
            $param = $this->_where_proset($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：' . 'proset');
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table('proset');
        $param = $this->_where_proset($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy('id', 'asc')->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . 'proset');
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        if ($data) {
            foreach ($data as $k => $v) {
                $data[$k]['addtime_date'] = date('Y-m-d H:i:s', $v['addtime']);
            }
        }
        $param['total'] = $total;
        return [$data, $total, $param];
    }

    //新增和编辑全部数据时验证
    private function _validate_proset($data, $id = 0)
    {
        if (!$data) {
            return ams_rt(1, '参数错误');
        } elseif (!$data['name']) {
            return ams_rt(1, '名称必须填写');
        } elseif (!$data['code']) {
            return ams_rt(1, '标识必须填写');
        }

        $flag = $this->field_exitsts('proset', 'name', $data['name'], $id);
        if ($flag) {
            return ams_rt(1, '名称已存在');
        }

        if (isset($data['code']) && $data['code']) {
            $flag = $this->field_exitsts('proset', 'code', $data['code'], $id);
            if ($flag) {
                return ams_rt(1, '标识已存在');
            }
        }

        return ams_rt(0, 'ok', $data);
    }

    //
    public function getCats()
    {
        $rows = $this->db->table('proset')->select('id,code,name')->get()->getResultArray();
        if (!$rows) {
            $rows = [];
        }
        return $rows;
    }

    //添加项目设置
    public function addProset($data)
    {
        $odata = $data;
        $rt = $this->_validate_proset($data);
        if ($rt['code']) {
            return $rt;
        }
        $data = $rt['data'];
        $data['addtime'] = time();
        $data['content'] = json_encode($data['content']);
        $data = esc($data);

        $this->db->table('proset')->insert($data);
        $id = $this->db->insertID();
        if ($id) {
            unset($odata);
            $data['id'] = $id;
            $data['content'] = json_decode($data['content'], true);
            return ams_rt(0, '操作成功', $data);
        }
        $msg = $this->db->error();
        return ams_rt(1, '操作失败:' . ($msg['message'] ?? ''));
    }

    //修改支付平台
    public function editProset($id, $data)
    {
        $odata = $data;
        $id = intval($id);
        $row = $this->db->table('proset')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        $data = esc($data);
        $rt = $this->_validate_proset($data, $id);
        if ($rt['code']) {
            return $rt;
        }

        $data = $rt['data'];
        $data['addtime'] = time();
        $data['content'] = json_encode($data['content']);
        $flag = $this->db->table('proset')->where('id', $id)->update($data);

        return ams_rt(0, '操作成功', $odata);
    }

    //删除支付平台
    public function delProset($id)
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $row = $this->db->table('proset')->select('id,name,code')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在', []);
        }
        $this->db->table('proset')->where('id', $id)->delete();
        return ams_rt(0, '操作成功', $row);
    }

    public function switchStatus($id)
    {
        $id = intval($id);
        if (!$id) {
            return ams_rt(1, '参数错误');
        }

        $row = $this->db->table('proset')->select('id,name,code,status')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        if ($row['status'] == 1) {
            $status = 0;
        } else {
            $status = 1;
        }
        $this->db->table('proset')->where('id', $id)->update(['status' => $status]);
        return ams_rt(0, '操作成功', $row);
    }

    public function setdisplayorder($id, $displayorder)
    {
        return $this->displayorder($this->table, $id, $displayorder);
    }

    //获取
    public function getInfoId($id)
    {
        $id = intval($id);
        $row = $this->db->table('proset')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return null;
        }
        $row['addtime_date'] = date('Y-m-d H:i', $row['addtime']);
        $row['content'] = json_decode($row['content'], true);
        if ($row['content'] && is_array($row['content'])) {
            foreach ($row['content'] as $v) {
                $row['config'][$v['key']] = $v['value'];
            }
        }
        return $row;
    }

    public function getInfoEvent($event)
    {
        ams_clean_xss($event);
        $row = $this->db->table('proset')->where('event', $event)->get()->getRowArray();
        if (!$row) {
            return null;
        }
        $row['content'] = json_decode($row['content'], true);
        if ($row['content'] && is_array($row['content'])) {
            foreach ($row['content'] as $v) {
                $row['config'][$v['key']] = $v['value'];
            }
        }
        $row['addtime_date'] = date('Y-m-d H:i', $row['addtime']);
        return $row;
    }

}
